﻿using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class TCPClient : TCPRemote
{
    bool m_ToPing;

    /// <summary>
    /// 最大ping失败次数
    /// </summary>
    public const int c_maxPingFailedCount = 3;

    /// <summary>
    /// ping时间间隔
    /// </summary>
    const float c_PingInterval = 3;

    /// <summary>
    /// 当前连续ping失败次数
    /// </summary>
    public int m_ContinueFailedCount;

    bool m_GetResponse;

    Timer m_Timer;

    public TCPClient(long id, TCPSocketServer _server,Action<TCPRemote> onDisconnect):base(id,_server,onDisconnect)
    {
        clientId = id;

        m_Timer = new Timer(OnTimeEnd);

        m_ToPing = true;

        //StartPing();
    }
    void StartPing()
    {
        m_GetResponse = false;
        m_Timer.Change(TimeSpan.FromSeconds(c_PingInterval), Timeout.InfiniteTimeSpan);
        //GameDebug.LogShowy($"StartPing");
        Ping();
    }

    void OnTimeEnd(object state)
    {
        if (!m_GetResponse)
        {
            m_ContinueFailedCount++;
            GameDebug.Log($"Ping失败，次数：{m_ContinueFailedCount}");
            if(m_ContinueFailedCount > c_maxPingFailedCount)
            {
                this.Disconnect();
            }
        }
        else
        {
            if (m_ToPing)
            {
                //GameDebug.Log("继续Ping");
                StartPing();
            }
            else
            {
                GameDebug.Log("已停止Ping");
            }
        }
    }

    void OnPingSuc()
    {
        m_GetResponse = true;
    }

    public override void OnRecOrSendFailed(EndPoint endPoint)
    {
        base.OnRecOrSendFailed(endPoint);

        m_ToPing = false;
    }

    public void Disconnect()
    {
        GameDebug.LogShowy($"{this.userID}  clientID:{this.clientId} userId:{this.userID} 强制断线");
        m_ToPing = false;

        this.OnRecOrSendFailed(this.m_EndPoint);
        //this.m_SocketServer as TCPSocketServer)?.TestDisconnect();
    }


    public void Ping()
    {
       // GameDebug.Log($"TCPClient  {this.clientId} userId:{this.userID}  发送Ping :{ipEndPoint}");

        //TODO.改为SendPacket
        if (m_SocketServer != null && ipEndPoint != null)
        {
            m_SocketServer._SendData(new byte[] { ClientsManagerBase.PingByte }, this.ipEndPoint);
        }
        else
        {
            GameDebug.LogError("m_SocketServer == null");
        }
    }

    public override void OnReceiveData(EndPoint endPoint, byte[] data)
    {
        if (data.Length == 1)
        {
            this.OnReceivePingResponse(data);
        }
        else
        {
           // GameDebug.Log($"client:{clientId}  userId:{userID}  处理数据");

            this.OnProcessMessageData(data);
        }
    }

    public void OnReceivePingResponse(byte[] data)
    {
        if (data.Length == 1 && data[0] == ClientsManagerBase.PingByte)
        {
            OnPingSuc();
            //GameDebug.Log($"client:{clientId}  userId:{userID}  ping 返回");
        }
        else
        {
            GameDebug.LogError($"OnReceivePingResponse data:{data.GetArrStr()}");
        }
    }

    public override string ToString()
    {
        return $"clientId:{this.clientId}  userID:{userID}";
    }
}
    

